#include <stdio.h>
#include <stdarg.h> // 变长参数头文件

/*
| `va_list`  | 定义参数列表指针 |
| `va_start` | 初始化参数列表   |
| `va_arg`   | 获取下一个参数   |
| `va_end`   | 清理参数列表     |
*/


void print(int count, ...)
{
    // 声明一个 参数列表
    va_list age_list;
    // 初始化 参数列表
    va_start(age_list, count);

    for (size_t i = 0; i < count; i++)
    {
        printf("%.2lf\t", va_arg(age_list, double));
        // va_arg(age_list , int)
        // age_list     参数列表
        // int          参数类型(传入的)
    }

    printf("\n");
}

void my_printf(const char *str, ...)
{
    // 扫描 有多少个 %

    // 每个参数的位置
    unsigned int type_index[128][2] = {0};
    // 第一个存位置 第二个存类型

    int val_agr = 0; // 获取参数个数

    for (size_t i = 0; '\0' != str[i]; i++)
    {
        if ('%' == str[i])
        {

            // 存储位置
            type_index[val_agr][0] = i;
            // 存储类型
            type_index[val_agr][1] = str[i + 1];

            val_agr++;
        }
    }

    // 创建列表
    va_list arg_list;

    // 初始化列表
    va_start(arg_list, str);

    // 打印出每个参数的类型
    for (size_t i = 0; i < val_agr; i++)
    {
        // 续写
        switch (type_index[i][1])
        {
        case 'd':
            printf("%d\n", va_arg(arg_list, int));
            break;
        case 'f':
            printf("%f\n", va_arg(arg_list, double));
            break;
        case 's':
            printf("%s\n", va_arg(arg_list, char *));
            break;
        case 'c':
            printf("%c\n", va_arg(arg_list, int));
            break;
        default:
            break;
        }
    }

    //释放列表
    va_end(arg_list);
}

int main(int argc, char const *argv[])
{
    print(4 , 20.1 , 30.2, 40.3 , 50.4);

    my_printf("张三 %d 李四 %f %c %s\n", 13, 13.4 , 'C' , "张三");
    return 0;
}